/****************************************
* Purpose: check Outliers in Data
*	 Date: 20230503	
****************************************/

%macro checkOutlier(indata /*输入数据集*/
					,vars  /*要检查异常值的变量列表,变量1|标准1\变量2|标准2...形式,1=均数标准差方式 2=四分位数间距*/
					,outdata=final /*输出数据集*/
					)/des="检查数据集异常值";
	%local numVars exeStatements;
	%let numVars=%sysfunc(countw(&vars,\));  	
	%do i=1 %to &numVars;
		%let temp=%scan(&vars,&i,\);
		%let var=%scan(&temp,1,|);
		%let crit=%scan(&temp,2,|);
		%put &var &crit;
		%if &crit=1 %then %do;
			proc sql noprint;
				select mean(&var),std(&var) into :m,:s
				from &indata;
			quit;
			%let crit1=%sysevalf(&m-3*&s);
			%let crit2=%sysevalf(&m+3*&s);
		%end;%else %if &crit=2 %then %do;
			ods output summary=t;
			proc means data=&indata p25 p75;
				var &var;
			run;
			ods output close;
			data _null_;
				set t;
				call symputx('p1',&var._p25);
				call symputx('p2',&var._p75);
			run;
			%put &p1 &p2;
			%let crit1=%sysevalf(&p1-3*(&p2-&p1));
			%let crit2=%sysevalf(&p2+3*(&p2-&p1));
		%end;
		%put NOTE: &var.  :&crit1.--&crit2.;
		%let exeStatements=&exeStatements if .<&var<&crit1. or &var>&crit2. then _out_&var.=1%str(;);
	%end; 
	data &outdata;
		set &indata;
		&exeStatements
		if sum(of _out_:)>=1;
	run;
	proc datasets lib=work nodetails nolist nowarn;
		delete t;
	quit;
%mend;